﻿<!DOCTYPE html>
<html>
<head>
  <title>HTML DOM Tree</title>
  <!-- Copyright 1998-2020 by Northwoods Software Corporation. -->
  <meta name="description" content="Interactive diagram showing the structure of the HTML DOM of this HTML page, allowing collapsing/expanding of subtrees." />
  <meta name="viewport" content="width=device-width, initial-scale=1">

  <script src="../release/go.js"></script>
  <script src="../assets/js/goSamples.js"></script>  <!-- this is only for the GoJS Samples framework -->
  <script id="code">
    var names = {}; // hash to keep track of what names have been used

    function init() {
      if (window.goSamples) goSamples();  // init for these samples -- you don't need to call this
      var $ = go.GraphObject.make;  // for conciseness in defining templates

      myDiagram =
        $(go.Diagram, "myDiagramDiv",
          {
            initialAutoScale: go.Diagram.UniformToFill,
            // define the layout for the diagram
            layout: $(go.TreeLayout, { nodeSpacing: 5, layerSpacing: 30 })
          });

      // Define a simple node template consisting of text followed by an expand/collapse button
      myDiagram.nodeTemplate =
        $(go.Node, "Horizontal",
          { selectionChanged: nodeSelectionChanged },  // this event handler is defined below
          $(go.Panel, "Auto",
            $(go.Shape, { fill: "#1F4963", stroke: null }),
            $(go.TextBlock,
              {
                font: "bold 13px Helvetica, bold Arial, sans-serif",
                stroke: "white", margin: 3
              },
              new go.Binding("text", "key"))
          ),
          $("TreeExpanderButton")
        );

      // Define a trivial link template with no arrowhead.
      myDiagram.linkTemplate =
        $(go.Link,
          { selectable: false },
          $(go.Shape));  // the link shape

      // create the model for the DOM tree
      myDiagram.model =
        $(go.TreeModel, {
          isReadOnly: true,  // don't allow the user to delete or copy nodes
          // build up the tree in an Array of node data
          nodeDataArray: traverseDom(document.activeElement)
        });
    }

    // Walk the DOM, starting at document, and return an Array of node data objects representing the DOM tree
    // Typical usage: traverseDom(document.activeElement)
    // The second and third arguments are internal, used when recursing through the DOM
    function traverseDom(node, parentName, dataArray) {
      if (parentName === undefined) parentName = null;
      if (dataArray === undefined) dataArray = [];
      // skip everything but HTML Elements
      if (!(node instanceof Element)) return;
      // Ignore the navigation menus
      if (node.id === "navindex" || node.id === "navtop") return;
      // add this node to the nodeDataArray
      var name = getName(node);
      var data = { key: name, name: name };
      dataArray.push(data);
      // add a link to its parent
      if (parentName !== null) {
        data.parent = parentName;
      }
      // find all children
      var l = node.childNodes.length;
      for (var i = 0; i < l; i++) {
        traverseDom(node.childNodes[i], name, dataArray);
      }
      return dataArray;
    }

    // Give every node a unique name
    function getName(node) {
      var n = node.nodeName;
      if (node.id) n = n + " (" + node.id + ")";
      var namenum = n;  // make sure the name is unique
      var i = 1;
      while (names[namenum] !== undefined) {
        namenum = n + i;
        i++;
      }
      names[namenum] = node;
      return namenum;
    }

    // When a Node is selected, highlight the corresponding HTML element.
    function nodeSelectionChanged(node) {
      if (node.isSelected) {
        names[node.data.name].style.backgroundColor = "lightblue";
      } else {
        names[node.data.name].style.backgroundColor = "";
      }
    }
  </script>
</head>
<body onload="init()">
<div id="sample">
  <!-- The DIV needs an explicit size or else we won't see anything. -->
  <div id="myDiagramDiv" style="border: 1px solid black; width:100%; height:300px"></div>
    <p>
        This sample shows the DOM (Document Object Model) of this webpage displayed as a tree.
        Each Node in the Diagram shows information about the corresponding HTML element in the DOM.
    </p>
    <p>
        When a node is selected, the background color of the corresponding HTML Element changes to lightblue.
        Below the diagram are some more HTML elements to illustrate the effect.
        This sample also makes use of the <a href="../intro/buttons.html" target="_blank">TreeExpanderButton</a>,
        which allows for parent nodes to expand and collapse their child nodes. Buttons are defined in <a href="../extensions/Buttons.js">Buttons.js</a>.
    </p>
  <p id="lastParagraph">
    Elements with an id attribute are noted in parenthesis.
  </p>
  <div id="otherInfo">
    <div id="tableContainer" style="display: inline-block;">
      <table style="border: 1px; border-collapse: collapse;">
        <tr>
        <th id="firstHeader">Table header</th>
        <th id="secondHeader">Table header 2</th>
        </tr>
        <tr>
        <td>row 1, cell 1</td>
        <td>row 1, cell 2</td>
        </tr>
        <tr>
        <td>row 2, cell 1</td>
        <td>row 2, cell 2</td>
        </tr>
      </table>
    </div>
    <div id="listContainer" style="display: inline-block; border: 1px solid gray; margin-left: 10px; width: 100px">
      <p>My grocery list</p>
      <ul id="groceryList">
        <li>Coffee</li>
        <li>Milk</li>
        <li>Bread</li>
      </ul>
    </div>
    <p>
        For more uses of the <a>TreeLayout</a> see the <a href="DOMTree.html">DOM Tree</a> and <a href="visualTree.html">Visual Tree</a> samples.
    </p>
  </div>
</div>
</body>
</html>